//
//  RxSwiftBinderObserverViewController.swift
//  DemoProject
//
//  Created by hao on 2018/7/27.
//  Copyright © 2018年 hao. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

/** 观察者: AnyObserver、Binder、自定义可绑定属性 */
class RxSwiftBinderObserverViewController: BaseViewController {

    lazy var label: UILabel! = {
        let _label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
        self.view.addSubview(_label)
        _label.textAlignment = .center
        _label.center = CGPoint(x: MainScreenWidth()*0.5, y: MainScreenHeight()*0.5)
        return _label
    }()
    
    lazy var button: UIButton! = {
        let _button = UIButton(type: .system)
        self.view.addSubview(_button)
        _button.frame = CGRect(x: 0, y: 0, width: 100, height: 30)
        _button.setTitle("观察者属性", for: .normal)
        _button.center = CGPoint(x: MainScreenWidth()*0.5, y: MainScreenHeight()*0.3)
        return _button
    }()
    
    // 只需要再次初始化 DisposeBag() 就能释放其对象所持有的订阅者
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
//        self.testBindObserver()
//        self.testAnyObserver()
//        self.testBindTo()
//        self.testBinderInCocoa()
//        self.customBinderProperty1()
        testRxCocoaProperty()
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        _ = DisposeBag()
    }

}

// MARK: Binder、AnyObserver
extension RxSwiftBinderObserverViewController {
    
    // bind 方法中创建
    fileprivate func testBindObserver() {
        // 创建一个每隔1秒就发送一个累加后的索引数(从0开始) Observable
        let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        // map()方法 可做一些操作 (索引数) -> (返回对象/可不需要)
        observable.map { value -> String in
            print(info: "map -> \(value)")
            return "当前索引数：\(value)"
        }.bind { [weak self] (text) in   // (map中的返回对象)
            self?.label.text = text
        }.disposed(by: disposeBag) // 将 observable 可观察对象添加到disposeBag对象管理
        // 下面的代码为简写
//        Observable<Int>.interval(1, scheduler: MainScheduler.instance)
//            .map { "当前索引数：\($0 )"}
//            .bind { [weak self](text) in
//                //收到发出的索引数后显示到label上
//                self?.label.text = text
//            }
//            .disposed(by: disposeBag)
    }
    
    // 使用 AnyObserver 创建观察者
    fileprivate func testAnyObserver() {
        let anyObserver = AnyObserver<String>.init { (event) in
            switch event {
                case .next(let data):
                    print(info: data)
                case .error(let error):
                    print(info: error)
                case .completed:
                    print(info: ".completed")
            }
        }
        _ = Observable.of("H", "A", "O").subscribe(anyObserver)
    }
    
    // 数据绑定
    fileprivate func testBindTo() {
        let anyObserver = AnyObserver<String>.init { [weak self] (event) in
            switch event {
                case .next(let text):
                    // 收到索引数后显示到label上
                    self?.label.text = text
                default:
                    break
            }
        }
        
        Observable<Int>.interval(2, scheduler: MainScheduler.instance)
            .map { "当前索引数: \($0)" }
            .bind(to: anyObserver)
            .disposed(by: disposeBag)
    }
    
}

// MARK: Binder 在 RxCocoa 中的应用
extension RxSwiftBinderObserverViewController {
    
    fileprivate func testBinderInCocoa() {
        // 循环改变button的交互状态
        Observable<Int>.interval(2, scheduler: MainScheduler.instance)
            .map { $0 % 2 == 0 }
            .bind(to: button.rx.isTestEnabled)
            .disposed(by: disposeBag)
    }
    
}

fileprivate extension Reactive where Base : UIControl {
    
    fileprivate var isTestEnabled : Binder<Bool> {
        return Binder.init(self.base, binding: { (control, value) in
            control.isEnabled = value
        })
    }
    
}

// MARK: 自定义可绑定属性
extension RxSwiftBinderObserverViewController {
    
    // 通过类扩展
    fileprivate func customBinderProperty1() {
        // 每0.5秒就执行一次字体放大
        Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
            .map { CGFloat($0) }
            .bind(to: label.testBindFont)
            .disposed(by: disposeBag)
    }
    
}

// 为 UILabel 扩展 自定义绑定属性 testBindFont 使用: bind(to: label.testBindFont)
fileprivate extension UILabel {
    
    fileprivate var testBindFont: Binder<CGFloat> {
        return Binder(self) { label, testBindFont in
            label.font = UIFont.systemFont(ofSize: testBindFont)
        }
    }
    
}
// 通过对 Reactive 类进行扩展 使用: bind(to: label.rx.testBindFont)
fileprivate extension Reactive where Base : UILabel {
    
    fileprivate var testBindFont: Binder<CGFloat> {
        return Binder(self.base) { label, testBindFont in
            label.font = UIFont.systemFont(ofSize: testBindFont)
        }
    }
    
}

// MARK: 使用RxCocoa的属性
extension RxSwiftBinderObserverViewController {
    
    fileprivate func testRxCocoaProperty() {
        Observable<Int>.interval(1.5, scheduler: MainScheduler.instance)
            .map{ "当前索引数: \($0)" }
            .bind(to: label.rx.text)
            .disposed(by: disposeBag)
    }
    
}


